package componentloader

import (
	"fmt"
	"strings"
	"zstackgo/spring"

	"github.com/go-spring/spring-core/gs"
	"github.com/meilihao/golib/v2/log"
)

// 负责解析conf/springConfigXml定义的Bean的自定义
type PluginDefinitionParser struct {
}

func getBeanClass(s string) string {
	s = strings.TrimPrefix(s, "zstackgo/pkg/")

	return strings.ReplaceAll(s, "/", ".")
}

func (p *PluginDefinitionParser) parsePlugin(beanDef *gs.BeanDefinition, id string, sexts []*spring.PluginExtension) []*PluginExtension {
	if len(sexts) == 0 {
		return nil
	}

	exts := make([]*PluginExtension, 0)
	for _, e := range sexts {
		ext := new(PluginExtension)
		ext.BeanName = id
		ext.BeanClassName = getBeanClass(beanDef.Type().Elem().PkgPath()) + "." + id

		if e.Interface != "" {
			ext.ReferenceInterface = e.Interface
		}
		if e.InstanceRef != "" {
			ext.InstanceId = e.InstanceRef
		}
		if e.Order != 0 {
			ext.Order = e.Order
		}

		exts = append(exts, ext)
	}
	return exts
}

func (p *PluginDefinitionParser) Decorate(my *spring.MyContainer, beanDef *gs.BeanDefinition, id string, sexts []*spring.PluginExtension) {
	if my.MapBeanIdDef[PliginRegistryBeanName] == nil {
		builder := new(PluginRegistryImpl)
		spring.Register(builder, PliginRegistryBeanName, nil)

		log.Glog.Debug("No BeanDefinition for PluginRegistry found, create and register one")
	}

	exts := p.parsePlugin(beanDef, id, sexts)
	if len(exts) == 0 {
		return
	}

	ext := exts[0]
	if defaultExtemsions == nil {
		defaultExtemsions = map[string][]*PluginExtension{}
		defaultExtemsions[ext.BeanClassName] = exts

		log.Glog.Debug("No 'extensions' property found in PluginRegistry bean definition, create a new one")
	} else {
		oexts, ok := defaultExtemsions[ext.BeanClassName]
		if ok {
			for _, e := range exts {
				for _, oe := range oexts {
					if e.BeanClassName == oe.BeanClassName {
						log.Glog.Fatal(fmt.Sprintf("duplicated extension declaration[interfaceRef:%s, beanName:%s, beanClass:%s]", e.ReferenceInterface, ext.BeanName, ext.BeanClassName))
					}
				}
				oexts = append(oexts, e)
			}
			defaultExtemsions[ext.BeanClassName] = oexts
		} else {
			defaultExtemsions[ext.BeanClassName] = exts
		}
	}

	//	log.Glog.Debug(fmt.Sprintf("Add extensions declared by bean[name=%s, class=%s] to 'extensions' property of PluginRegistry bean definition", ext.BeanName, ext.BeanClassName))
}
